import os
from typing import Dict, List, Optional, Any

import requests
from bs4 import BeautifulSoup
from dotenv import load_dotenv
from langchain_core.tools import tool

from config.logging_config import get_logger
# 导入通用工具管理器
from tools.ToolManager import ToolManager, SingleToolConfig

# 设置日志
logger = get_logger(__name__)

# 加载环境变量
load_dotenv()


# 搜索结果类
class SearchResult:
    def __init__(self, title: str, url: str, description: str, source: str):
        self.title = title
        self.url = url
        self.description = description
        self.source = source

    def to_dict(self) -> Dict:
        return {
            "title": self.title,
            "url": self.url,
            "description": self.description,
            "source": self.source
        }

    def __str__(self) -> str:
        return f"{self.title} ({self.url})\n{self.description}"


# 搜索引擎基类
class SearchEngine:
    def __init__(self, name: str):
        self.name = name

    def search(self, query: str, num_results: int = 5) -> List[SearchResult]:
        """执行搜索并返回结果"""
        raise NotImplementedError("搜索引擎必须实现search方法")


# Google搜索引擎 (使用SerpAPI)
class GoogleSearchEngine(SearchEngine):
    def __init__(self):
        super().__init__("google")
        self.api_key = os.environ.get("SERPAPI_API_KEY")

    def search(self, query: str, num_results: int = 5) -> List[SearchResult]:
        if not self.api_key:
            logger.warning("未设置SERPAPI_API_KEY环境变量")
            return []

        try:
            params = {
                "engine": "google",
                "q": query,
                "api_key": self.api_key,
                "num": num_results
            }

            response = requests.get("https://serpapi.com/search", params=params)
            if response.status_code != 200:
                logger.error(f"SerpAPI请求失败: {response.status_code}")
                return []

            data = response.json()
            results = []

            # 解析搜索结果
            for item in data.get("organic_results", [])[:num_results]:
                results.append(SearchResult(
                    title=item.get("title", ""),
                    url=item.get("link", ""),
                    description=item.get("snippet", ""),
                    source="google"
                ))

            return results

        except Exception as e:
            logger.error(f"Google搜索出错: {str(e)}")
            return []


# 百度搜索引擎
class BaiduSearchEngine(SearchEngine):
    def __init__(self):
        super().__init__("baidu")

    def search(self, query: str, num_results: int = 5) -> List[SearchResult]:
        try:
            headers = {
                "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36"
            }

            response = requests.get(
                f"https://www.baidu.com/s?wd={query}",
                headers=headers
            )

            if response.status_code != 200:
                logger.error(f"百度搜索请求失败: {response.status_code}")
                return []

            # 使用BeautifulSoup解析结果
            soup = BeautifulSoup(response.text, "html.parser")
            results = []

            # 查找结果容器
            containers = soup.select(".result.c-container")
            for container in containers[:num_results]:
                title_elem = container.select_one(".t")
                link_elem = container.select_one("a")
                abstract_elem = container.select_one(".c-abstract")

                title = title_elem.get_text() if title_elem else ""
                url = link_elem.get("href") if link_elem else ""
                description = abstract_elem.get_text() if abstract_elem else ""

                results.append(SearchResult(
                    title=title,
                    url=url,
                    description=description,
                    source="baidu"
                ))

            return results

        except Exception as e:
            logger.error(f"百度搜索出错: {str(e)}")
            return []


# 网络搜索工具
class WebSearchTool:
    def __init__(self):
        self.engines = {
            "google": GoogleSearchEngine(),
            "baidu": BaiduSearchEngine()
        }
        self.default_engine = "google"

    def set_default_engine(self, engine_name: str) -> None:
        """设置默认搜索引擎"""
        if engine_name in self.engines:
            self.default_engine = engine_name
            logger.info(f"默认搜索引擎已设置为: {engine_name}")
        else:
            logger.error(f"未知的搜索引擎: {engine_name}")

    def add_engine(self, engine: SearchEngine) -> None:
        """添加新的搜索引擎"""
        self.engines[engine.name] = engine
        logger.info(f"已添加搜索引擎: {engine.name}")

    def search(self, query: str, engine: Optional[str] = None, num_results: int = 5) -> List[SearchResult]:
        """执行搜索，支持指定引擎或使用默认引擎"""
        engine_name = engine or self.default_engine

        if engine_name not in self.engines:
            logger.error(f"未知的搜索引擎: {engine_name}")
            return []

        logger.info(f"使用 {engine_name} 引擎搜索: {query}")
        return self.engines[engine_name].search(query, num_results)

    def search_all(self, query: str, num_results: int = 5) -> Dict[str, List[SearchResult]]:
        """使用所有可用引擎执行搜索"""
        results = {}
        for name, engine in self.engines.items():
            logger.info(f"使用 {name} 引擎搜索: {query}")
            results[name] = engine.search(query, num_results)
        return results


# 创建WebSearchTool实例
_web_search_tool = WebSearchTool()


@tool
def web_search(query: str, engine: str = "google", num_results: int = 5) -> str:
    """
    在网络上搜索信息。
    
    参数:
        query: 要搜索的查询内容
        engine: 可选，指定搜索引擎 (google/baidu)，默认使用google
        num_results: 可选，返回结果数量，默认为5
    
    返回:
        格式化的搜索结果文本
    """
    try:
        # 记录更详细的日志
        logger.info(f"开始执行网络搜索: 查询={query}, 引擎={engine}, 结果数量={num_results}")

        # 执行搜索
        results = _web_search_tool.search(query, engine, num_results)

        # 记录搜索结果信息
        if not results:
            logger.info(f"搜索结果: 未找到任何匹配内容 (查询={query}, 引擎={engine})")
            return f"使用 {engine} 搜索 '{query}' 未找到结果"

        logger.info(f"搜索完成: 找到 {len(results)} 条结果 (查询={query}, 引擎={engine})")

        # 格式化结果
        output = [f"搜索 '{query}' 的结果:"]
        for i, result in enumerate(results, 1):
            output.append(f"\n{i}. {result.title}")
            output.append(f"   链接: {result.url}")
            output.append(f"   描述: {result.description}")
            logger.info(f"搜索结果 #{i}: 标题='{result.title}', URL={result.url}")

        return "\n".join(output)

    except Exception as e:
        logger.error(f"网络搜索过程中出错: {str(e)}, 查询={query}, 引擎={engine}")
        return f"搜索出错: {str(e)}"


@tool
def set_search_engine(engine: str) -> str:
    """
    设置默认搜索引擎。

    参数:
        engine: 搜索引擎名称 (google/baidu)

    返回:
        设置结果消息
    """
    try:
        logger.info(f"尝试设置默认搜索引擎: {engine}")

        # 验证搜索引擎名称
        if engine not in _web_search_tool.engines:
            supported_engines = ', '.join(_web_search_tool.engines.keys())
            logger.warning(f"尝试设置不支持的搜索引擎: {engine}，支持的引擎: {supported_engines}")
            return f"错误: 不支持的搜索引擎 '{engine}'。支持的引擎: {supported_engines}"

        # 设置搜索引擎
        old_engine = _web_search_tool.default_engine
        _web_search_tool.set_default_engine(engine)
        logger.info(f"成功将默认搜索引擎从 {old_engine} 更改为 {engine}")

        return f"默认搜索引擎已从 {old_engine} 更改为 {engine}"

    except Exception as e:
        logger.error(f"设置搜索引擎时出错: {str(e)}, 尝试设置的引擎: {engine}")
        return f"设置搜索引擎出错: {str(e)}"


@tool
def get_search_engine_status() -> str:
    """
    获取当前搜索引擎状态。

    返回:
        当前搜索引擎配置信息
    """
    try:
        current_engine = _web_search_tool.default_engine
        supported_engines = list(_web_search_tool.engines.keys())

        status_info = [
            f"当前默认搜索引擎: {current_engine}",
            f"支持的搜索引擎: {', '.join(supported_engines)}"
        ]

        # 检查API密钥状态
        if hasattr(_web_search_tool.engines.get('google'), 'api_key'):
            google_api_status = "已配置" if _web_search_tool.engines['google'].api_key else "未配置"
            status_info.append(f"Google API密钥状态: {google_api_status}")

        logger.info(f"获取搜索引擎状态: 当前引擎={current_engine}")
        return "\n".join(status_info)

    except Exception as e:
        logger.error(f"获取搜索引擎状态时出错: {str(e)}")
        return f"获取状态出错: {str(e)}"


class WebSearchToolManager(ToolManager):
    """网络搜索工具集管理器"""

    @property
    def category_name(self) -> str:
        return "网络搜索工具集"

    @property
    def category_code(self) -> str:
        return "web_search_toolkit"

    @property
    def category_description(self) -> str:
        return "提供完整的网络搜索功能工具集，包括网络搜索、搜索引擎配置和状态查询功能，支持Google和百度搜索引擎"

    def get_tool_configs(self) -> List[Dict[str, Any]]:
        # 工具1：网络搜索
        web_search_tool = SingleToolConfig(
            tool_id=1,
            tool_name="web_search",
            description="在网络上搜索信息，支持Google和百度搜索引擎",
            is_enabled=True
        )

        web_search_tool.add_parameter(
            param_name="query",
            param_type="string",
            description="要搜索的查询内容",
            is_required=True
        )

        web_search_tool.add_parameter(
            param_name="engine",
            param_type="string",
            description="搜索引擎类型：google(谷歌)、baidu(百度)",
            default_value="google",
            is_required=False
        )

        web_search_tool.add_parameter(
            param_name="num_results",
            param_type="integer",
            description="返回结果数量，默认为5",
            default_value=5,
            is_required=False
        )

        # 工具2：设置搜索引擎
        set_engine_tool = SingleToolConfig(
            tool_id=2,
            tool_name="set_search_engine",
            description="设置默认搜索引擎，支持Google和百度",
            is_enabled=True
        )

        set_engine_tool.add_parameter(
            param_name="engine",
            param_type="string",
            description="搜索引擎名称：google(谷歌)、baidu(百度)",
            is_required=True
        )

        # 工具3：获取搜索引擎状态
        status_tool = SingleToolConfig(
            tool_id=3,
            tool_name="get_search_engine_status",
            description="查看当前搜索引擎配置状态和支持的引擎列表",
            is_enabled=True
        )

        return [
            web_search_tool.to_dict(),
            set_engine_tool.to_dict(),
            status_tool.to_dict()
        ]

    def get_langchain_tool(self):
        """返回工具集中的所有工具"""
        return [web_search, set_search_engine, get_search_engine_status]


# 创建全局实例
web_search_toolkit_manager = WebSearchToolManager()

logger.info("WebSearch工具初始化完成, 支持的引擎: google, baidu")
